----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    20:02:49 09/26/2013 
-- Design Name: 
-- Module Name:    div - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use Ieee.std_logic_unsigned.all;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity div is
	port(	clock, load : in STD_LOGIC;
			n, d : in STD_LOGIC_VECTOR(31 downto 0);
			quotient : out STD_LOGIC_VECTOR(31 downto 0);
			remainder : out STD_LOGIC_VECTOR(31 downto 0));
end div;

architecture Behavioral of div is
	component op_counter is
		port(	clock : in STD_LOGIC;
				reset : in STD_LOGIC;
				max : in STD_LOGIC_VECTOR(5 downto 0);
				count : out STD_LOGIC_VECTOR(5 downto 0));
	end component;
	
	component adder_32 is
		Port ( a : in  STD_LOGIC_VECTOR (31 downto 0);
				 b : in  STD_LOGIC_VECTOR (31 downto 0);
             carryIn : in  STD_LOGIC;
             sum : out  STD_LOGIC_VECTOR (31 downto 0);
             carryOut : out  STD_LOGIC);
	end component;
	
	signal counterReset : STD_LOGIC := '0';
	signal max : STD_LOGIC_VECTOR(5 downto 0) := "011111";
	signal count : STD_LOGIC_VECTOR(5 downto 0);
	signal addItem1: STD_LOGIC_VECTOR (31 downto 0) := X"00000000";
	signal addItem2: STD_LOGIC_VECTOR (31 downto 0) := X"00000000";
	signal sum: STD_LOGIC_VECTOR (31 downto 0) := X"00000000";
	signal carryIn : STD_LOGIC := '0';
	signal carryOut : STD_LOGIC := '0';
begin
	counter1 : op_counter port map(clock, counterReset, max, count);
	adder : adder_32 port map(addItem1,addItem2,carryIn,sum,carryOut);
process(clock)
	variable rqReg: STD_LOGIC_VECTOR(64 downto 0) := '0' & X"0000000000000000";
	variable dividend33 : STD_LOGIC := '0';
begin
	if clock'event and clock = '1' then
		rqReg (63 downto 32) := sum;
		if count /= "011111" then
			counterReset <= '0';
			rqReg(64) := rqReg(64) xor dividend33 xor carryOut;
			rqReg (0) := not(rqReg(64));
			if count = "011110" then
				addItem1 <= rqReg (63 downto 32);
				carryIn  <= '0';
				if rqReg(64) = '1' then
					addItem2 <= d;
				else
					addItem2 <= X"00000000";
				end if;
			else
				addItem1 <= rqReg (62 downto 31);
				dividend33 := not(rqReg(64));
				carryIn <= dividend33;
				rqReg := rqReg(63 downto 0) & '0';
				if rqReg(64) = '1' then
					addItem2 <= d;
				else
					addItem2 <= not(d);
				end if;
			end if;
		elsif load = '1' then
			--Immediate shift of bits when division is set to begin
			rqReg := X"00000000" & n & '0';
			addItem1 <= rqReg (63 downto 32);
			addItem2 <= not(d);
			dividend33 := '1';
			carryIn  <= '1';
			counterReset <= '1';
		else 
			counterReset <= '0';
			addItem1 <= rqReg (63 downto 32);
			addItem2 <= X"00000000";
			carryIn  <= '0';
		end if;
		
		quotient <= rqReg(31 downto 0);
		remainder <= rqReg(63 downto 32);
	end if;
end process;
end Behavioral;

